Docker Compose Use Environment Variables Like a Pro

Finding yourself building, rebuilding, and deploying Docker containers? My stack of NodeJS projects have started to unruly, and I need a better way to deploy my apps with little fuss.

Env Vars

Keep your environment variables in one place. You'll start pulling your hair out if they're split between .env, compose.yml, envs.ts, etc. I recommend keeping them all in .env

.env

NODE_ENV="production"

IMAGE_FRONTEND_NAME="cutefruit-kypn-frontend"
IMAGE_BACKEND_NAME="cutefruit-kypn-backend"

SITE_TITLE="MY COOL SITE"
SITE_DESC="Learn how to use env like a pro"
ADMIN_EMAIL_ADDRESS="Enviroment@Variables.lan"

import in compose.yml

version: '3'

services:

  backend:
    container_name: ${IMAGE_BACKEND_NAME}
    image: ${IMAGE_BACKEND_NAME}:latest 
    restart: unless-stopped
    build: 
      context: ./
      dockerfile: ./Dockerfile.backend
    # ports: # expose this if you're not using a proxy
    #   - 3001:3001
    networks:
      - this

  frontend:
    container_name: ${IMAGE_FRONTEND_NAME}
    image: ${IMAGE_FRONTEND_NAME}:latest # rename ALL 'cutefruit-kypn' to a unique name 
    restart: unless-stopped
    build: 
      context: ./
      dockerfile: ./Dockerfile.frontend
    # ports: # expose this if you're not using a proxy
    #   - 3000:3000
    networks:
      - this

networks:    
  this:
    name: cutefruit-kypn-network
    driver: bridge  
    external: true 

If all you tweaked was the .env file, then just hit the container with the docker compose up -d and it should replace the new values

Import in Bash Scripts

#!/bin/bash

source .env

# if you're having stale configuration/environment issues, 
# add the --no-cache argument
# docker compose build --no-cache
docker compose build 

docker save -o "./images/$IMAGE_FRONTEND_NAME.tar" $IMAGE_FRONTEND_NAME
docker save -o "./images/$IMAGE_BACKEND_NAME.tar" $IMAGE_BACKEND_NAME

Excellent for bash scripting. In the above example I'm setting the file name to match the container and image name ${IMAGE_FRONTEND_NAME}

Import in Javascript, Typescript

Wrap your env variables in a envs.ts has benefits

// FRONTEND      
const SITE_TITLE          = process.env.NEXT_PUBLIC_SITE_TITLE! 
const SITE_DESC          = process.env.NEXT_PUBLIC_SITE_DESC! 
const ADMIN_EMAIL_ADDRESS = process.env.NEXT_PUBLIC_ADMIN_EMAIL_ADDRESS!

export const envs = {
  SITE_TITLE,
  SITE_DESC,
  ADMIN_EMAIL_ADDRESS,
} 

Import

Credits